﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.WindowsAzure.StorageClient;
using WebRole1.Search.Query;

namespace Microsoft.WindowsAzure.Search
{
    class Query
    {
        public static Dictionary<String, String> MakeQuery(String input, CloudBlobContainer indexContainer, CloudBlobContainer dataContainer)
        {
            CloudStorageAccount account =
                CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

            // parse query to unique terms
            List<String> queryTerms = QueryParser.Parse(input);

            List<String> aQueryTerms = new List<String>();
            List<String> gQueryTerms = new List<String>();
            List<String> qQueryTerms = new List<String>();

            foreach (String term in queryTerms)
            {
                if ('a' <= term[0] && term[0] <= 'f')
                {
                    aQueryTerms.Add(term);
                    continue;
                }

                if ('g' <= term[0] && term[0] <= 'p')
                {
                    gQueryTerms.Add(term);
                    continue;
                }

                if ('q' <= term[0] && term[0] <= 'z')
                {
                    qQueryTerms.Add(term);
                    continue;
                }
            }

            CloudBlob[] indexBlobs = new CloudBlob[3];
            indexBlobs[0] = indexContainer.GetBlobReference("indexa");
            indexBlobs[1] = indexContainer.GetBlobReference("indexg");
            indexBlobs[2] = indexContainer.GetBlobReference("indexq");

            // get index content
            // <term, entry>
            Dictionary<String, Entry> aDictionary = new Dictionary<String,Entry>();
            Dictionary<String, Entry> gDictionary = new Dictionary<String,Entry>();
            Dictionary<String, Entry> qDictionary = new Dictionary<String,Entry>();

            Dictionary<String, Entry> dictionary = new Dictionary<String, Entry>();

            if (aQueryTerms.Count != 0)
                aDictionary = IndexParser.Parse(indexBlobs[0], aQueryTerms);

            if (gQueryTerms.Count != 0)
                gDictionary = IndexParser.Parse(indexBlobs[1], gQueryTerms);

            if (qQueryTerms.Count != 0)
                qDictionary = IndexParser.Parse(indexBlobs[2], qQueryTerms);

            foreach (KeyValuePair<String, Entry> pair in aDictionary)
            {
                dictionary.Add(pair.Key, pair.Value);
            }

            foreach (KeyValuePair<String, Entry> pair in gDictionary)
            {
                dictionary.Add(pair.Key, pair.Value);
            }

            foreach (KeyValuePair<String, Entry> pair in qDictionary)
            {
                dictionary.Add(pair.Key, pair.Value);
            }

            // get docInfo Content
            String[] docLines = DocInfoParser.Parse(indexContainer);

            // get document length (normalization factor)
            double[] lengths = DocInfoParser.GetDocLength(docLines);

            // compute cosine score
            double[] scores = Rank.ComputeCosine(dictionary, lengths, queryTerms);

            // <docID, score> for displaying scores of each document
            Dictionary<int, double> scoreDic = new Dictionary<int, double>();
            for (int i = 0; i < lengths.Length; i++)
                scoreDic.Add(i, scores[i]);

            // top rank documents
            List<String> documents = Rank.GetTopRankDocs(scoreDic, docLines);

            // get corresponding context lines
            List<String> contextLines = Context.GetContextLines(dataContainer, queryTerms, documents);

            // Add documents and context lines to the dictionary, and return the result
            Dictionary<String, String> docContext = new Dictionary<String, String>();
            for (int i = 0; i < documents.Count; i++)
            {
                docContext.Add(documents[i], contextLines[i]);
            }

            return docContext;
        }
    }
} 
